#include "XBone.h"

XBone::XBone(){
	m_name = "UNKNOWN";
	m_parent = NULL;
	m_dirty = true;
	m_skel_buffer = NULL;
}
XBone::~XBone(){

}

void XBone::SetOffest(Vector3 pos){
	m_offest = pos;
	m_dirty = true;
}

void XBone::SetRotation(Quaternion rot){
	m_rotation = rot;
	m_dirty = true;
}

void XBone::UpdateBone(){
	if (m_parent == NULL){
		m_abs_rotation =  m_rotation;
		m_abs_offest = m_offest;
	}
	else{
		if (!m_dirty)
			return;
		m_abs_rotation = m_parent->m_abs_rotation * m_rotation;
		m_abs_offest  = m_abs_rotation * m_offest + m_parent->m_abs_offest;
	}
	if (m_dirty){
		if (m_skel_buffer == NULL){
			XRender::GetInstance()->CreateVertexBuffer(&m_skel_buffer, 2 * sizeof(Vector3), true, false, 0);
			Vector3* buffer = new Vector3[2];
			if (m_parent == NULL)
				buffer[0] = Vector3(0.0f, 0.0f, 0.0f);
			else
				buffer[0] = m_parent->m_abs_offest;
			buffer[1] = m_abs_offest;
			m_skel_buffer->SetSourceBuffer(buffer, 0, 2 * sizeof(Vector3));
			free(buffer);
		}
		else{
			Vector3* buffer = new Vector3[2];
			buffer[0] = m_parent->m_abs_offest;
			buffer[1] = m_abs_offest;
			m_skel_buffer->SetSourceBuffer(buffer, 0, 2 * sizeof(Vector3));
			free(buffer);
		}
	}
	CalcFinalTransformMatrix();
}

void XBone::CalcOriginTransformMatrix(){
	Matrix3 rot;
	m_abs_rotation.ToRotationMatrix(rot);
	//rot.Transpose();
	Matrix4 final(rot);
	final.SetOffset(m_abs_offest);
	m_origin_matrix = final;
}

void XBone::CalcFinalTransformMatrix(){
	if (!m_dirty)
		return;
	Matrix3 rot;
	m_abs_rotation.ToRotationMatrix(rot);
	//rot.Transpose();
	Matrix4 final(rot);
	final.SetOffset(m_abs_offest);
	m_trans_matrix = m_origin_matrix * final;
	m_dirty = false;
}

Matrix4 XBone::GetTransformMatrix(){
	return m_trans_matrix;
}

void XBone::RenderBone(){
	XRender::GetInstance()->SetRenderStream(0, m_skel_buffer, 0, 12);
	XRender::GetInstance()->DrawLine(0, 2);
}